package com.basker.pisces.tools.diagnosis;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import com.basker.pisces.domain.command.meta.Command;
import com.basker.pisces.domain.entity.meta.AbstractEntity;
import com.basker.pisces.domain.entity.meta.ChildEntity;
import com.basker.pisces.domain.entity.meta.Entity;
import com.basker.pisces.domain.property.meta.EnumProperty;
import com.basker.pisces.domain.property.meta.Property;
import com.basker.pisces.domain.property.meta.StatusProperty;
import com.basker.pisces.domain.value.meta.EnumOption;
import com.basker.pisces.domain.value.meta.StatusOption;

@Lazy
@Component
public class EntityDiagnoser {

    /**
     * 诊断指定实体元素的显示名称属性，可以快速排查哪些元素没有配置合理的显示值或资源文件key
     *
     * @param entityName
     * @return
     */
    public Map<String/* Name */, Object/* DisplayName */> diagnoseElementDisplayName(Entity entity) {
        // 将实体、属性、命令的DispalyName显示出来
        Map<String/* Name */, Object/* DisplayName */> desc = new LinkedHashMap<>();

        desc.put(entity.getName(), entity.getDisplayName());

        this.fillPropertyDisplayName(desc, entity);
        this.fillCommandDisplayName(desc, entity);

        return desc;
    }

    private void fillCommandDisplayName(Map<String, Object> desc, Entity entity) {
        for (Command command : entity.getCommands()) {
            desc.put(command.getName(), command.getDisplayName());
        }
    }

    private void fillPropertyDisplayName(Map<String, Object> desc, AbstractEntity entity) {
        for (Property<?> property : entity.getProperties()) {
            desc.put(property.getName(), property.getDisplayName());

            if (property instanceof EnumProperty) {
                List<EnumOption> options = ((EnumProperty) property).getOptions();

                for (EnumOption option : options) {
                    desc.put(property.getName() + ":" + option.getId(), option.getDisplayName());
                }
            }

            if (property instanceof StatusProperty) {
                List<StatusOption> options = ((StatusProperty) property).getOptions();

                for (StatusOption option : options) {
                    desc.put(property.getName() + ":" + String.valueOf(option.getStatusValue()),
                            option.getDisplayName());
                }
            }
        }

        for (ChildEntity chdEntity : entity.getChildEntities()) {
            this.fillPropertyDisplayName(desc, chdEntity);
        }
    }

}
